package com.cxm.helper.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxm.helper.enums.MessageBusinessTypeEnum;
import com.cxm.helper.exception.BusinessException;
import com.cxm.helper.pojo.Article;
import com.cxm.helper.pojo.Category;
import com.cxm.helper.pojo.Message;
import com.cxm.helper.pojo.User;
import com.cxm.helper.pojo.dto.MessageListDTO;
import com.cxm.helper.pojo.vo.MessageVO;
import com.cxm.helper.pojo.vo.UserVO;
import com.cxm.helper.service.ArticleService;
import com.cxm.helper.service.CategoryService;
import com.cxm.helper.service.MessageService;
import com.cxm.helper.mapper.MessageMapper;
import com.cxm.helper.service.UserService;
import com.cxm.helper.util.BeanUtil;
import com.cxm.helper.util.response.PageResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author chenximeng
 * @description 针对表【message】的数据库操作Service实现
 * @createDate 2022-12-03 12:51:25
 */
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message>
        implements MessageService {

    @Autowired
    MessageMapper messageMapper;
    @Autowired
    UserService userService;
    @Autowired
    ArticleService articleService;
    @Autowired
    CategoryService categoryService;
    @Autowired
    RabbitMqService rabbitMqService;

    @Override
    public PageResponse<MessageVO> pageList(MessageListDTO request) {
        Page<Message> page = new Page<>(request.getCurrent(), request.getSize());
        QueryWrapper<Message> wrapper = new QueryWrapper<>();
        wrapper.eq("receive_user_id", StpUtil.getLoginIdAsLong());
        wrapper.orderByDesc("id");
        List<Message> messages = messageMapper.selectPage(page, wrapper).getRecords();
        if (CollUtil.isEmpty(messages)) {
            return new PageResponse<>(page, CollUtil.newArrayList());
        }
        List<MessageVO> records = BeanUtil.copyList(messages, MessageVO.class);
        formatMsgRecords(records);
        rabbitMqService.readMsg(JSONUtil.toJsonStr(records.stream().map(MessageVO::getId).collect(Collectors.toList())));
        return new PageResponse<>(page, records);
    }

    @Override
    public Integer getNewMsgNum(Long receiveUserId) {
        return count(new QueryWrapper<Message>().eq("receive_user_id", receiveUserId).eq("status", 0));
    }

    private void formatMsgRecords(List<MessageVO> records) {
        List<Long> sendUserIds = records.stream().map(MessageVO::getSendUserId).collect(Collectors.toList());
        List<User> sendUsers = userService.listByIds(sendUserIds);
        User loginUser = userService.getById(StpUtil.getLoginIdAsLong());
        List<UserVO> userVOS = BeanUtil.copyList(sendUsers, UserVO.class);
        Map<Long, UserVO> userMap = userVOS.stream().collect(Collectors.toMap(UserVO::getId, item -> item));
        Map<Integer, List<MessageVO>> typeMap = records.stream().collect(Collectors.groupingBy(MessageVO::getBusinessType));
        for (Integer businessType : typeMap.keySet()) {
            switch (Objects.requireNonNull(MessageBusinessTypeEnum.getEnumByCode(businessType))) {
                case ARTICLE:
                    List<Long> articleIds = typeMap.get(businessType).stream().map(MessageVO::getBusinessId).collect(Collectors.toList());
                    List<Article> articles = articleService.listByIds(articleIds);
                    List<Long> categoryIds = articles.stream().map(Article::getCategoryId).collect(Collectors.toList());
                    Map<Long, String> categoryNameMap = categoryService.listByIds(categoryIds).stream().collect(Collectors.toMap(Category::getId, Category::getName));
                    Map<Long, Article> articleMap = articles.stream().collect(Collectors.toMap(Article::getId, item -> item));
                    for (MessageVO messageVO : typeMap.get(businessType)) {
                        Article article = articleMap.get(messageVO.getBusinessId());
                        messageVO.setReference(article.getTitle());
                        messageVO.setCategoryName(categoryNameMap.get(article.getCategoryId()));
                        messageVO.setSendUser(userMap.get(messageVO.getSendUserId()));
                        messageVO.setReceiveUsername(loginUser.getNickname());
                    }

                default:
            }
        }

    }

}




